refactor(primitives): strip old composite editor + recognizeComposite (~2.2k LoC)#2
Open
pyenthu wants to merge 5 commits into
Open
refactor(primitives): strip old composite editor + recognizeComposite (~2.2k LoC)#2pyenthu wants to merge 5 commits into
pyenthu wants to merge 5 commits into
Conversation
…point + tagInstanceSources First step of stripping the old composite editor stack. The K.63 .asm.ts CompositionEditor (+ .rev.ts / .exp.ts builders) is the survivor; the pre-K.63 const-declarations-+-return-chain UI keyed off recognizeComposite is going away. Removed: - src/routes/api/primitives/recognize/+server.ts (HTTP wrapper for recognizeComposite) - src/lib/shared/ConstructionTree.svelte (BODMAS visualization for the old composite shape) - src/lib/server/primitive-loader.ts::tagInstanceSources + the recognize-composite import — color-by-source stamping is owned by the K.63 assembly emit (composition-tree.ts wraps each Call with __tag(...) at compose time). Old .prim.ts composites fall back to a single uniform colour through CSG; that's acceptable per the strip spec. In PrimitiveView.svelte: - Drop the ConstructionTree import + the <ConstructionTree /> mount. - loadRecognition() now no-ops (recognized = null) — keeps the call sites compiling while phase 4 cuts them. Avoids spamming 404s against the now-deleted /api/primitives/recognize endpoint. Smoke tests against http://localhost:3333 (parent .dev-volume): - /api/primitives/source?name=r_revolve 200 (stdlib source served) - /api/primitives/preview r_revolve 200 (positions returned) - /api/primitives/preview r_cube 200 - /api/primitives/preview r_tube 200 - /api/primitives/preview r_cube_ball 200 (composite leaf, OK) - /api/primitives/preview r_thread_full 200 - /api/primitives/preview r_cylinder 200 - /api/primitives/recognize 404 (deleted) Build clean. Composite leaf .prim.ts files still load + render; the inspector UI for them shrinks down to Parameters + Source + viewer in phase 4. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the recognizeComposite branch from analyzeParts (the old composite
primitive path) — the K.63 assembly walk (analyzeAssembly) was already
the front-end, so the recognizer-driven fallback was dead code.
After this phase:
- analyzeParts only reads meta.composition (.asm.ts shape) and walks
the TreeNode for Call aliases + their CSG role.
- .prim.ts files without meta.composition fall through to INACTIVE
(the renderer's material/heuristic colour path takes over). That
matches what tagInstanceSources no longer does in the loader: old
composites lose per-part colour-by-source but render fine.
- analyzeAssembly is the single implementation; analyzeParts wraps it.
- The recognize-composite import is removed.
Same call surface as before (analyzeParts(source) → PartColorLUT), so
the four consumers — /api/primitives/{preview,bake-preview},
src/routes/fem/[id]/tension/TensionScene.svelte, and the doc comment in
builder.ts — keep working without changes.
Smoke (parent .dev-volume primitives):
- /api/primitives/preview r_revolve 200
- /api/primitives/preview r_cube 200
- /api/primitives/preview r_tube 200
- /api/primitives/preview r_cube_ball 200
- /api/primitives/preview r_thread_full 200
- /api/primitives/preview r_cylinder 200
Build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Zero code consumers left after phases 1+2: tagInstanceSources is gone,
analyzeParts no longer falls back to recognizeComposite, and the
/api/primitives/recognize endpoint was deleted. The 481-line parser
goes with them.
Comments + plan/details.ts still REFERENCE the file by name (historical
narrative); those stay as-is per the strip spec ("don't touch routes/
or docs").
Smoke (parent .dev-volume):
- /api/primitives/preview r_revolve 200
- /api/primitives/preview r_cube 200
- /api/primitives/preview r_tube 200
- /api/primitives/preview r_cube_ball 200
- /api/primitives/preview r_thread_full 200
- /api/primitives/preview r_cylinder 200
Build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The big one. PrimitiveView.svelte shrinks from 3387 → ~1700 lines: the
pre-K.63 const-declarations-+-return-chain composite editor is gone.
What survives for non-asm parts is exactly what the strip spec specified:
Parameters accordion (with polygon-leaf ✎ popup for type:'profile'
params), Source tab, AI tab, and the PrimitiveDualCanvas viewer.
Removed STATE:
- recognized / recogStatus / recogError / loadRecognition
- usesSet / parts / locals / resolvedParts / canEdit's recognized? gate
- profileEdit / profilePts / profileBaseline / promoteBusy / profileDirty
- colorPopup + instanceColorsSpan / readInstanceColors /
serializeInstanceColors / setPartColor / openColorPopup / pickColor /
partColors (the per-instance outer/inner swatches; CompositionEditor
has its OWN matching helpers for .asm.ts files)
- profileSwap + openProfileSwap / closeProfileSwap / swapPartProfile
- TRANSFORMS / txAdd / openTxAdd / closeTxAdd / addTransform / deleteTransform
- fxEdit / fxParams / openFx / openProfileFx / closeFx / fxAppend / applyFx
- warpPathEdit / DEFAULT_WARP_PATH / isWarped / showTree /
toggleWarpEnd / openWarpPath / closeWarpPath / applyWarpPath
- deletePart
- loadPick / loadable / loadBusy / uniqueInstName / defaultArgFor /
loadPrimitive (sidebar drag-to-canvas + Load picker scaffolder)
- splitTopLevelArgs / spliceArg
- leafProfileCache / leafMetaCache / fetchLeafProfile / profileInfoFor +
the LeafProfile type — only the COMPOSITE part-row consumed these
- functionalProfileForSeg / hasResolveProfile / kindFromResolveCall /
profileRefName
- partProfileKind / partProfileFn / profileSchemaForKind /
partProfileParamNames / pickSchema / partProfileLoc / parseDescriptor
/ partProfileParamsView / applyPartProfileRaw / setPartProfileParamRaw
(lifted-profile-params inside a recognized part row)
- regenRevolveSource / leafKindOptions
- openInstanceFnEditor / swapEditorProfile / fnEditor.bind
- pickProfileShape / profilePtsPreview / applyProfile / closeProfilePopup
/ promoteProfile / suggestProfileName / openProfilePopup
Replaced (still works for .prim.ts add/delete-param):
- primParamInsertSpans() — regex over meta.params + signature, replaces
the old recognized.{paramsInsertPos,sigInsertPos} from
recognizeComposite.
- primParamLoc(name) — regex over meta.params entry + signature token,
replaces recognized.params[i].{entryStart,entryEnd,sigStart,sigEnd}.
- paramBlockedReason now scans the function body via regex (was the
same approach the asm path already used).
Kept whole:
- kind dispatch for asm / rev / exp (CompositionEditor /
RevolvePartBuilder / ExtrudePartBuilder).
- Parameters accordion + ParamGrid + the polygon cards for
type:'profile' params (still drive the leaf-profile ✎ popup).
- + param / ✕ param flow (regex-based for .prim.ts, addAssemblyParam /
removeAssemblyParam for .asm.ts).
- Save / Apply / Revert / ↺ / Save defaults / Save As / Duplicate / Delete
header buttons.
- Source tab + AI tab.
- The leaf profile popup (openLeafProfile / leafEdit / pickPaletteProfile
/ setLeafKind / setLeafParam / setLeafPoints / volProfiles + the
saveProfilePanel for "save profile → volume").
- The ProfileFnEditor floating panel (fnEditor, simplified to target:'leaf'
only since the instance-bind path is gone).
Template:
- Big composite Parts panel + per-row UI replaced with a one-liner:
asm sources mount CompositionEditor; .prim.ts + stdlib show only the
Parameters accordion above (no Parts panel).
- profileEdit / warpPathEdit / profileSwap / colorPopup / fxEdit / txAdd
FloatingPanels deleted.
Smoke (parent .dev-volume via local-→-prod proxy):
- /api/primitives/preview my_assy (asm, params [4.5, 0.7]) 200 (18432 pos)
- /api/primitives/preview spiral (prim, [3,0,12,-0.5,96,5,0.5,0.12]) 200 (2304)
- /api/primitives/preview collar_taper 200 (1536)
- /api/primitives/preview r_revolve (stdlib) 200
Build clean. primitives chunk: 223KB → 186KB (gzip 49→41KB).
Existing .prim.ts files on the volume can still load + view + edit
params + edit Source. Composite editing (add/remove/swap/recolor
parts) is no longer available for them — per the strip spec, that's
accepted.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the dead INSTANCE_PALETTE + colorsForInstance import from PrimitiveView (only the deleted composite-instance swatch popup used them; CompositionEditor owns the asm equivalent). - Update the tagManifold doc comment in manifold-helpers.ts to point at composition-tree.emitNode + analyzeAssembly (the K.63 path) instead of "wrapped around each recognized named instance by buildPrimitiveGeom" (that loader pass was removed in phase 1). No behaviour change. Build clean; smoke tests still 200 for my_assy / spiral / collar_taper / r_revolve. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jun 13, 2026
…ze, block save on errors From the GRAPH_EDITOR_REVIEW + the robustness plan's P1: - Removed the top-level window keydown listener that leaked one anonymous handler per component instance (multi-tab); folded the Esc-exits-poly-mode into onWindowKeydown (registered + cleaned up in onMount). (review #1) - refreshCallArgs now goes through finalize() (newly exported from composition-graph) instead of a raw node-spread, so graph.edges/imports rebuild after a drift-refresh (no stale phantom wires / wrong orphan detection). (review #2) - Save button disabled when emitted.validationErrors.length > 0 — can no longer save a graph with broken node refs that won't reload. (plan 1e) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jun 14, 2026
Archive the 2026-06-01 K.63 tree-editor survey verbatim (cad_authoring_patterns.archived-2026-06-01.md) and write a current successor that (a) reconciles which 2026-06-01 recommendations we kept, dropped, or REVERSED — notably §F3 'don't add a 2D node-canvas', which the shipped GraphEditorPane inverts — and (b) answers 'what is our possibility' for smooth/curved geometry: cadtrain is an OpenSCAD-class mesh-CSG / polygon-sampling kernel (NOT BREP), so Tier-1 dense continuous-function sampling is reachable today, Tier-2 sketch+spline+fillet needs one sketch_repeat engine fix, Tier-3 true BREP is explicitly out of class. Also add docs/plans/wavy-star.md — the concrete g_wavy_star (#2) + g_star_smooth (#1) build plan that the smoothness investigation produced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jun 17, 2026
…mode works calculateNormals(3, crease) returns an ALL-ZERO normal buffer on welded/revolved meshes (g_shaft etc.), so flat shading worked (face-derived) but smooth shading (flatShading:false → vertex normals) had nothing to shade with — "no shading". - builder.ts: detect degenerate normals (normalsDegenerate / bakedNormalsDegenerate) and recompute. Indexed paths (manifoldToGeo) computeVertexNormals directly; the NON-indexed color-by-source + cutVC paths build smooth normals from the indexed topology first (indexedSmoothNormals) then scatter — a plain computeVertexNormals on non-indexed geo would be FLAT. Winding is outward-consistent (Manifold canonicalises it), so the recomputed normals face outward (verified: g_shaft side normals 100% radial-outward, 0 inward). - bake-worker-core: bump KERNEL_VERSION (+nrm2) so stale zero-normal meshes in the client IndexedDB cache re-bake. (Server bake cache: cleared via /api/cache/clear.) Verified: g_shaft renders smooth radial shading in smooth mode (client + server), correctly lit (not inverted). Fixes TODO PARKED #1/#2. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jun 25, 2026
The engine already had it (compileSketch scaleX/scaleY + setSketchScale mutator + emit that drops sx/sy at 1/1 → byte-identical); this adds the missing UI — a ⚙ button in the sketch tool rail + a popover with independent X(r)/Y(z) inputs + Reset 1×1, writing literal ArgValues via setSketchScale. 2D canvas stays in design space; scale flows downstream to bake. Build+test green; verified Y=2→sketch(...,1,2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
User-supplied research consolidated INTO our stack (not a parallel system): compact TS tool schemas (local-model lever, cloud already prompt-cached), Claude-synthetic prompt→call pairs seeding the #27 corpus, few-shot injection via RAG-P3 embeddings now + optional LoRA fine-tune (Qwen2.5-1.5B #2 / Mistral-7B) later, Neo4j/Chroma parked (Rule 1). Ties to #27/#2/#1. Research doc docs/research/local-fncall-synthetic-data.md + TODO #28. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
…bLLM+MLC+XGrammar) Consolidate user research on running a FINE-TUNED small model fully in-browser into the AI research docs. New "In-browser deployment (WebLLM + MLC + XGrammar)" section in local-fncall-synthetic-data.md (#28, the deploy half of the fine-tune endgame): Qwen2.5-Coder-0.5B (4-bit <350MB, offline via Cache-Storage), MLC-LLM AOT compile + host + custom-URL CreateMLCEngine, XGrammar CFG constrained to our EDITOR_TOOLS/ArgValue syntax, zero-system-prompt-after-fine-tune, output -> dispatchEditorTool on the in-memory Graph (no server). Honest risks flagged (XGrammar = syntax not semantics; MLC compile is a real build step; ~350MB hosting; 0.5B accuracy = conditional-GO spike; few-shot is the near-term win). Cross-linked from web-llm-functionary.md (#2). TODO #2 + #28 pointered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
…l + data-residency Merge worktree-agent-aef8bf37 — extends #28 with the "In-browser deployment (WebLLM + MLC + XGrammar)" section (Coder-0.5B, MLC compile→wasm, XGrammar CFG from EDITOR_TOOLS → dispatchEditorTool, zero-prompt-after-fine-tune, honest risks) + TODO #2/#28 pointers. Plus a data-residency banner: prod restricts sending prompt data out → local runtime is a REQUIREMENT, cloud = dev/build-time only (memory ai_data_residency_local_first). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
… / future)
SVTC-style backend picker in AiMenu, pluggable via ge-assist's postTurn seam: a
registry {id,label,kind,postTurn,needsKey} — Claude (cloud, key) / WebLLM (local,
no key = data-residency) / future entries. Keys handled SECURELY (Rule 15 —
env/Railway/settings, never pasted-to-disk); local WebLLM needs none. Component
of the AI master plan; extends #2. docs/plans/ai-backend-selector.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
… reconcile One self-improving, local-first tool-calling assistant: one registry (source of truth) generates cloud schema / prompt / local XGrammar CFG, feeds one corpus (parts+docs+simplified+feedback) into one multi-shot loop, grows from judged turns, targets a local WebLLM runtime under data-residency. Sequenced P0-P4 roadmap (shipped-vs-todo marked). Reconciles #1/#2/#27/#28/#29 as phases: plan-header banners, TODO umbrella + annotations, /plan task 905 (stale->done, residual->P1), fix-errors sink superseded by #27, path/tool-count fixes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 1, 2026
#1/#2/#27/#28/#29) North star docs/plans/ai-master-plan.md: one function-library registry → generates cloud/prompt/local-CFG schemas → one multi-shot loop on the live Graph ← one corpus (parts+docs+simplified+feedback) → feedback grows it → local WebLLM runtime, under data-residency. 5 AI plans banner'd as detail-sheets under it; TODO #0 umbrella + #1/#2/#27/#28/#29 annotated as phases; stale /plan task 905 fixed (open→done); fix-errors sink marked superseded by #27. Cross-linked the backend-selector (P3) + #31 stays a separate editor track. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 5, 2026
…peat (#1) /api/tf/compile re-fetched every composite dep on EVERY edit, each a prod-proxied /api/primitives/source round-trip (the ~300ms 'compile' segment). Dep sources are param-invariant, so cache them by id (module-level, 60s TTL, negative entries too). A 🔄 rebake sends bust:true → bypasses the cache for a fresh resolve. Measured on bw_open_hole: cold 378ms → warm 1-2ms → 🔄 312ms. TODO #2 (parallelize the BFS frontier) noted in the endpoint header. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 5, 2026
… invalidation Logs the two TF-compile perf follow-ups after #1 (dep-source cache) shipped: (a) parallelize buildCompositeMap's BFS frontier (N×latency → depth×latency), (b) invalidate SRC_CACHE on part Save so a dep-source edit is instant across parts (with the local-dev prod-proxy wrinkle documented). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 5, 2026
…0ms → ~300ms (#2) resolveDepColors (part-colors.ts) re-fetched every composite dep with a RAW uncached fetch on EVERY /api/primitives/compile (colours computed outside the script cache) — the ~940ms 'still being compiled' latency on the hidden 3D bake. Now routes through the loader's exported fetchDepSource (30s TTL cache). GET compile measured 0.94s → 0.30s warm; the client POST path skips the root fetch too. TODOs logged: only-bake-active-tab (stop the hidden 3D-bake on the TF tab) + TF_WASM tab (C++→WASM builders for concealment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pyenthu
pushed a commit
that referenced
this pull request
Jul 10, 2026
…mic page Files the exploration under the local-first AI umbrella, where the binding data-residency constraint and the existing web-llm spike (#2) already live. Framed as a spike, not a build. Three things the entry pins down so the work doesn't start from the wrong end: - LiteRT.js COMPLEMENTS #2 rather than replacing it — it is the right runtime for small task-specific models (classifiers, embedders, regressors), where an LLM-shaped runtime is the wrong shape and far too heavy. - "Dynamic page" was unscoped, so the entry lists candidate surfaces best-first (semantic part search over the RAG corpus; /vocab inference triage; bake-cost prediction; wells element classification) and explicitly rules OUT silhouette retrieval: the cold-classification baseline already scored 17/18 with no retrieval, and CLIP embeddings collapsed on 12/18 default-param renders. Re-run that baseline before adding any model. - Names the real blockers up front: app-wide COOP/COEP require-corp already broke a main-thread WASM fetch once (Manifold on /wells), weights must ship same-origin under the strict CSP, and it must be default-OFF, lazy, and gated on the active tab. Deliverable is a written go/no-go with measured latency + bundle cost against the non-ML baseline it has to beat. The API surface is recalled, not verified — the entry says so, and says to check current docs first. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsYaPm3zaeuWL3KrPdCR8V
pyenthu
pushed a commit
that referenced
this pull request
Jul 11, 2026
… undo + pure part/kind/intent maps (#42b-B) Decision #2: WSON is the single source of truth for well editing (in-place mutation keeps doc identity stable, avoiding bake thrash). This lands the pure, headless-tested core of that layer; the Svelte editor wiring is deferred. WellEditCore — add session-batched undo (beginEdit/endEdit/session): a burst of edits in one focus session coalesces to ONE undo entry (SVTC's beginEditSession parity). Only the first mutation in a session snapshots; later ones mutate live (onChange still fires per edit) but add no history. Nestable (outermost pair bounds it); undo/redo/reset force-close the session. In-place restore + root-object identity preservation are unchanged. well-part-map.ts (new) — baked-part-id → WSON reverse maps: - layerForPartId(id) → WellLayerFlags key, accepting BOTH the emit var name (OH_/CEM_/CSG_/COMP_, the real WellPart.id) and the bw_* registry id. - parsePartId + inspectorElementForPartId — 3D pick → inspector cross-link, resolving the 1-based var-name index back to the source element. well-edit-intent.ts (new) — editor-intent glue: - kindToArrayKey(kind) → WSON array key (inspector onEdit routing). - addElementIntent(type) — tool-rail Add → concrete default element + target array; completion categories map to a registry tool_comp that resolves to that category. applyAddElement routes it through the undoable core. Tests: +20 core session-batch cases, +33 across the two new maps (all mapping helpers pinned against real samples/*.wson + the live registry). Full wells suite 311 green; bun run build green; tsc clean on the changed files. No Svelte files touched (browser-only, out of scope). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsYaPm3zaeuWL3KrPdCR8V
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Strips the pre-K.63 composite-editor stack from
/primitives. The K.63.asm.tsCompositionEditor+.rev.tsRevolvePartBuilder+.exp.tsExtrudePartBuilder+ leaf-profile popup (ProfileFnEditor) + assembly-sidepartHashIdcolor-by-source flow are the survivors.User signed off — "the old one can go."
.prim.tsfiles on the volume remain readable / param-editable / source-editable; composite editing (per-instance args, profile-swap, color swatches, delete-part, construction tree, warp toggle) is no longer available for them — accepted per the strip spec.Phases
Phase 1 (
fdaf55d) — drop ConstructionTree + recognize endpoint + tagInstanceSourcesRemoved
src/routes/api/primitives/recognize/+server.ts+src/lib/shared/ConstructionTree.svelte+tagInstanceSources(the loader-side per-instance__tag(...)wrap is unnecessary now that the K.63 assembly emit already wraps each Call at compose time).loadRecognitionno-ops to keeploadRecognitioncallsites compiling until phase 4 cuts them.Phase 2 (
e73de62) — collapse analyzeParts to assembly-onlysrc/lib/server/part-colors.ts: drop therecognizeCompositebranch.analyzeAssembly(the K.63 path) is the sole implementation;analyzeParts(source)dispatches there. Same call surface, so the four consumers (preview, bake-preview, TensionScene, builder.ts doc) are untouched.Phase 3 (
099c403) — delete recognize-composite.ts481 lines gone; zero code consumers remain. Plan/details narrative still references the name (historical); that stays.
Phase 4 (
b64fdfa) — strip the composite UI from PrimitiveViewThe big one.
PrimitiveView.sveltefrom 3387 → ~1700 lines. Removed:recognizedstate +parts/locals/resolvedPartsderivations; the args-edit popup; profile-swap popup; per-instance color popup (colorPopup+instanceColorsSpan/readInstanceColors/serializeInstanceColors/setPartColor); add-transform popup; delete-part button; per-row ƒ-expression popup; warp-at-end toggle + warp-path popup;loadPrimitive(sidebar drag-to-canvas + Load picker); the leaf-profile cache (fetchLeafProfile/profileInfoFor/splitTopLevelArgs) that only the composite part-row consumed;partProfile*helpers (partProfileLoc/parseDescriptor/partProfileParamsView/applyPartProfileRaw/setPartProfileParamRaw);openInstanceFnEditor/swapEditorProfile/fnEditor.bind(the part-binding flow);pickProfileShape/profilePtsPreview/applyProfile/promoteProfile;regenRevolveSource/leafKindOptions/functionalProfileForSeg/kindFromResolveCall. Replaced therecognized-driven+param/✕paramflow withprimParamInsertSpans()/primParamLoc(name)regex-based splices. Template's old composite Parts panel + the 6 dead floating panels (profileEdit/warpPathEdit/profileSwap/colorPopup/fxEdit/txAdd) removed.Phase 5 (
23a400a) — cleanup sweepDropped the dead
INSTANCE_PALETTE+colorsForInstanceimport fromPrimitiveView. Updated thetagManifolddoc comment inmanifold-helpers.tsto point atcomposition-tree.emitNode+analyzeAssemblyinstead of the deleted loader pass.What survives
Default branch (
.prim.ts+ stdlib): Parameters accordion (withParamGrid+ polygon-leaf ✎ popup fortype:'profile'params) ++ param/✕ paramflow + Source tab + AI tab + PrimitiveDualCanvas viewer + Save/Apply/Revert/Save defaults/Save As/Duplicate/Delete header buttons + the read-only stdlib banner.kind === 'asm'→CompositionEditor(unchanged).kind === 'rev'→RevolvePartBuilder(unchanged).kind === 'exp'→ExtrudePartBuilder(unchanged).Files
Deleted:
src/lib/server/recognize-composite.tssrc/lib/shared/ConstructionTree.sveltesrc/routes/api/primitives/recognize/+server.tsModified:
src/lib/server/part-colors.ts(167 → 124 lines, single-branch)src/lib/server/primitive-loader.ts(droptagInstanceSources)src/lib/shared/PrimitiveView.svelte(3387 → 1764 lines)src/lib/cad/manifold-helpers.ts(doc comment update)Smoke test results
/api/primitives/previewmy_assy(asm)[4.5, 0.7]/api/primitives/previewspiral(prim)[3, 0, 12, -0.5, 96, 5, 0.5, 0.12]/api/primitives/previewcollar_taper(prim)/api/primitives/previewr_revolve(stdlib)/api/primitives/recognize¹ Inline cylinder descriptor passed via the JSON-string param channel; the engine returns ok=true with an empty mesh because the dial value mismatches the descriptor. The end-to-end path still works — the call doesn't error.
Build clean throughout (one commit per phase, build verified after each).
/primitiveschunk: 223 KB → 186 KB.Things to know
.prim.tsfiles on the volume STILL LOAD + view + edit params + edit source. They lose composite editing (the per-instance args / profile selector / color swatch / delete-part / construction tree / warp toggle).r_revolve,r_extrude,r_weld_extrude) remain viewable read-only with the param accordion + polygon-leaf profile selector + Source + viewer — exactly the spec.analyzePartsretained as the export name (no consumer rename); just dispatches toanalyzeAssemblyformeta.compositionsources andINACTIVEotherwise. Composite.prim.tsfiles lose per-part color-by-source; renderer falls back to material/heuristic colors for them. Per the strip spec.recognize-composite+ConstructionTreeremain (historical).main.🤖 Generated with Claude Code